# -*- coding:utf-8 -*-
"""
@author: ksf

@since: 2020-04-25 17:12
"""
import os
import json
from typing import List
import pandas as pd

from vcat.core.obj import *
from vcat import LUCKY_CAT_PATH
from vcat.config import conf
from vcat.utils.utils import ensure_directory
from vcat.core.event import EventType, Event


class BaseFileStoreManager:

    def store_file_name(self):
        return os.path.join(LUCKY_CAT_PATH,  f'{self.__class__.__name__}.json')

    def load_from_store(self):
        file = self.store_file_name()
        with open(file, mode='r+') as f:
            return json.load(f)

    def save(self, json_data):
        file = self.store_file_name()
        with open(file, mode='w+') as f:
            json.dump(json_data, fp=f)


class AbstractApp:
    """
    标准插件，可以在 apps， brokers中具体实现
    """

    def __init__(self, engine):
        self._engine = engine

    def set_up(self):
        raise NotImplementedError

    def tear_down(self):
        raise NotImplementedError


class AbstractMetrics:

    def get_result(self):
        raise NotImplementedError


class GuardAlgo:

    def __init__(self, guard_obj, name, contract_ids, evnet_list: List[EventType], **kwargs):
        self._guard_obj = guard_obj
        self._name = name
        self._contract_ids = contract_ids
        self._event_list = evnet_list
        self._kwargs = kwargs

    @property
    def name(self):
        return self._name

    @property
    def contract_ids(self):
        return self._contract_ids

    @property
    def event_list(self):
        return self._event_list

    def on_data(self, data):
        raise NotImplementedError


class BaseGateway:

    @dataclass
    class ConfigSetting(MetaObj):

        userid: int = 0
        password: str = ''
        brokerid: str = ''
        td_address: str =''
        md_address: str = ''
        appid: str = ''
        auth_code: str = ''


        @classmethod
        def meta(cls):
            _meta = DivMetaInfo(
                name='登录CTP',
                title='CTP-Gateway',
                headers=[
                    TagMetaInfo(name='用户名', field='userid', value=cls.userid),
                    TagMetaInfo(name='密码', field='password', value=cls.password),
                    TagMetaInfo(name='经纪商代码', field='brokerid', value=cls.brokerid),
                    TagMetaInfo(name='交易服务器', field='td_address', value=cls.td_address),
                    TagMetaInfo(name='行情服务器', field='md_address', value=cls.md_address),
                    TagMetaInfo(name='产品名称', field='appid', value=cls.appid),
                    TagMetaInfo(name='授权编码', field='auth_code', value=cls.auth_code)
                ]
            )
            return _meta.to_dict()

    config_setting = ConfigSetting()

    gateway_name = 'base_gateway'

    def __new__(cls, *args, **kwargs):
        cls = super().__new__(cls)
        cls.load()
        return cls

    def __init__(self, engine):
        self.engine: "MainEngine" = engine

    def connect(self, params):
        raise NotImplementedError

    def subscribe(self, contract_list: List[ContractData]):
        raise NotImplementedError

    def send_order(self, req: OrderRequest) -> List[OrderData]:
        raise NotImplementedError

    def cancel_order(self, order_id):
        raise NotImplementedError

    def query_account(self):
        raise NotImplementedError

    def query_order(self):
        raise NotImplementedError

    def query_position(self):
        raise NotImplementedError

    def on_contract(self, contract: ContractData):
        self.engine.guard_left.put(Event(event_type=EventType.CONTRACT, data=contract))

    def on_tick(self, tick: TickData):
        self.engine.guard_left.put(Event(event_type=EventType.TICK, data=tick))

    def on_account(self, account: AccountData):
        self.engine.guard_left.put(Event(event_type=EventType.ACCOUNT, data=account))

    def on_position(self, position: PositionData):
        self.engine.guard_left.put(Event(event_type=EventType.POSITION, data=position))

    def on_order(self, order: OrderData):
        self.engine.guard_left.put(Event(event_type=EventType.ORDER, data=order))

    def on_trade(self, trade: TradeData):
        self.engine.guard_left.put(Event(event_type=EventType.TRADE, data=trade))

    def write_log(self, msg):
        self.engine.write_log(msg)

    @classmethod
    def get_path(cls):
        ensure_directory(os.path.join(conf.CUSTOM_DIR, 'gateway'))
        return os.path.join(conf.CUSTOM_DIR, 'gateway', f'{cls.gateway_name}.json')

    def save(self):

        path = self.get_path()
        print('保存配置到', path)
        with open(path, mode='w') as f:
            json.dump(self.config_setting.to_dict(), fp=f)

    def load(self):
        path = self.get_path()
        try:
            with open(path, mode='r') as f:
                settings = json.load(f)
                for k in self.config_setting.to_dict().keys():
                    setattr(self.config_setting, k, settings.get(k))
        except FileNotFoundError:
            pass

class BaseHistoryFeeder:

    AUTH_INFO = {
        'username': '',
        'password': ''
    }

    def login(self, params):
        raise NotImplementedError

    def get_all_contracts(self) -> pd.DataFrame:
        raise NotImplementedError

    def get_history(self, contract_ids: List[str], start_dt, end_dt, count=None, freq=DataLevel.minute) -> pd.DataFrame:
        raise NotImplementedError


class AbstractMarketDataApi:
    pass


class AbstractTradeApi:
    pass


class Slippage:
    @classmethod
    def process_order(cls, order, filling_price):
        pass

    @classmethod
    def to_dict(cls):
        pass


if __name__ == '__main__':
    from vcat.core.engine import MainEngine